package com.code.wflow.utils;

import com.alibaba.fastjson2.JSON;
import com.code.wflow.constants.NodeTypeEnum;
import com.code.wflow.model.InstanceNode;
import com.code.wflow.model.InstanceNodeDetail;
import com.code.wflow.model.WorkflowNode;
import com.code.wflow.node.NodeProperties;
import com.code.wflow.node.SupportSelfSelectNodeProperties;
import com.code.wflow.vo.AssignedUserApprovalVO;
import com.code.wflow.vo.InstanceNodeVO;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author ggh
 * @date 2022/11/25
 * 流程实例解析
 */
public class InstanceUtils {

    /**
     * 构建流程申请
     *
     * @param instanceNodeList
     * @return
     */
    public static String buildWorkflowInstance(List<InstanceNode> instanceNodeList, Map<Long, WorkflowNode> nodeMap,
                                               Map<Long, List<InstanceNodeDetail>> detailMap) {
        if (CollectionUtils.isEmpty(instanceNodeList) || nodeMap == null || detailMap == null
                || nodeMap.isEmpty() || detailMap.isEmpty()) {
            return null;
        }

        List<InstanceNodeVO> instanceNodeVOList = new ArrayList<>(instanceNodeList.size());

        for (InstanceNode instanceNode : instanceNodeList) {
            InstanceNodeVO instanceNodeVo = new InstanceNodeVO();

            WorkflowNode node = nodeMap.get(instanceNode.getWorkflowNodeId());
            instanceNodeVo.setType(node.getType());
            instanceNodeVo.setName(node.getName());
            instanceNodeVo.setCode(node.getCode());
            instanceNodeVo.setParentCode(node.getParentCode());
            instanceNodeVo.setStage(instanceNode.getStage());
            instanceNodeVo.setIsPass(instanceNode.getStatus());

            NodeTypeEnum nodeTypeEnum = NodeTypeEnum.parse(node.getType());
            NodeProperties properties = JSON.parseObject(node.getProps(), nodeTypeEnum.getCls());
            // 将自选对象填充到节点属性中
            if (NodeTypeEnum.APPROVAL.getType().equals(node.getType()) || NodeTypeEnum.CC.getType().equals(node.getType())) {
                SupportSelfSelectNodeProperties supportSelfSelectNodeProperties = (SupportSelfSelectNodeProperties) properties;
                List<InstanceNodeDetail> detailList = detailMap.get(instanceNode.getId());

                List<AssignedUserApprovalVO> approvalVos = new ArrayList<>(detailList.size());

                for (InstanceNodeDetail detail : detailList) {
                    AssignedUserApprovalVO approvalVo = new AssignedUserApprovalVO();
                    approvalVo.setId(detail.getExecutorId());
                    approvalVo.setName("");
                    approvalVo.setStatus(detail.getStatus());
                    approvalVo.setRemark(detail.getRemark());
                    approvalVos.add(approvalVo);
                }
                supportSelfSelectNodeProperties.setAssignUser(approvalVos);
                instanceNodeVo.setProps(supportSelfSelectNodeProperties);
            } else {
                instanceNodeVo.setProps(properties);
            }

            instanceNodeVOList.add(instanceNodeVo);
        }

        InstanceNodeVO rootVo = instanceNodeVOList.stream()
                .filter((vo) -> vo.getParentCode() == null)
                .findFirst()
                .get();

        buildChilden(rootVo, instanceNodeVOList);

        return JSON.toJSONString(rootVo);
    }

    private static void buildChilden(InstanceNodeVO rootVo, List<InstanceNodeVO> instanceNodeVOList) {
        instanceNodeVOList.stream().forEach((vo) -> {
            if (!StringUtils.isEmpty(vo.getParentCode()) && vo.getParentCode().equals(rootVo.getCode())) {
                buildChilden(vo, instanceNodeVOList);
                rootVo.setChildren(vo);
            }
        });
    }
}
